﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using Autodesk.Revit.UI.Selection;
using YRevitJig;

namespace YArchitech.Plumbing
{
	internal class FireHydrantJig : XUiJigBase
	{
		public FireHydrantJig(UIDocument uiDoc, Curve c) : base(uiDoc)
		{
			this.curve = c;
		}

		public XYZ GetStartPoint(Selection sel)
		{
			this.StartXYZ = sel.PickPoint("选择插入点");
			return this.StartXYZ;
		}

		public XYZ GetEndPoint(Selection sel)
		{
			return sel.PickPoint("选择消火栓方向");
		}

		public override void Draw(PaintEventArgs paintEventArgs)
		{
			base.Draw(paintEventArgs);
			if (this.StartXYZ != null)
			{
				System.Drawing.Point ptCur = this.m_ptCur;
				if (!this.m_ptCur.IsEmpty && paintEventArgs != null)
				{
					XYZ xyz = base.Client2Revit(this.m_ptCur);
					XGraphics xgraphics = new XGraphics(paintEventArgs.Graphics, base.JigPen);
					if (!(this.curve == null))
					{
						XYZ xyz2 = new XYZ(0.0, 1.0, 0.0);
						XYZ xyz3 = new XYZ(0.0, -1.0, 0.0);
						XYZ xyz4 = new XYZ(1.0, 0.0, 0.0);
						XYZ xyz5 = new XYZ(-1.0, 0.0, 0.0);
						XYZ xyz6 = (this.curve.GetEndPoint(0) - this.curve.GetEndPoint(1)).Normalize();
						if (xyz6.X > 0.0)
						{
							xyz4 = xyz6;
							this.setDirection(xyz4, ref xyz5, ref xyz2, ref xyz3);
						}
						else if (xyz6.X == 0.0)
						{
							if (xyz6.Y > 0.0)
							{
								xyz4 = xyz6;
							}
							else
							{
								xyz4 = -xyz6;
							}
							xyz5 = -xyz4;
							xyz2 = this.getVVectorY(xyz4)[1];
							xyz3 = this.getVVectorY(xyz4)[0];
						}
						else
						{
							xyz4 = -xyz6;
							this.setDirection(xyz4, ref xyz5, ref xyz2, ref xyz3);
						}
						this.setLineForDraw(xgraphics, xyz2);
						this.setLineForDraw(xgraphics, xyz3);
						this.setLineForDraw(xgraphics, xyz4);
						this.setLineForDraw(xgraphics, xyz5);
						double num = xyz4.AngleTo(xyz - this.StartXYZ);
						double num2 = xyz2.AngleTo(xyz - this.StartXYZ);
						XYZ xyz7;
						XYZ xyz8;
						XYZ thPt;
						if (num < Math.PI*.5)
						{
							if (num2 < Math.PI*.5)
							{
								this.location = FireHydrantLocation.FHL_UPRIGHT;
								new XLine2D(base.Revit2Client(this.StartXYZ + xyz4), base.Revit2Client(this.StartXYZ + xyz4 + xyz2)).Draw(xgraphics);
								new XLine2D(base.Revit2Client(this.StartXYZ + xyz4 + xyz2), base.Revit2Client(this.StartXYZ + xyz5 + xyz2)).Draw(xgraphics);
								new XLine2D(base.Revit2Client(this.StartXYZ + xyz5 + xyz2), base.Revit2Client(this.StartXYZ + xyz5)).Draw(xgraphics);
								xyz7 = this.StartXYZ + xyz5;
								xyz8 = this.StartXYZ + xyz4 + xyz2;
								thPt = this.StartXYZ + xyz4;
							}
							else
							{
								this.location = FireHydrantLocation.FHL_DOWNRIGHT;
								new XLine2D(base.Revit2Client(this.StartXYZ + xyz4), base.Revit2Client(this.StartXYZ + xyz4 + xyz3)).Draw(xgraphics);
								new XLine2D(base.Revit2Client(this.StartXYZ + xyz4 + xyz3), base.Revit2Client(this.StartXYZ + xyz5 + xyz3)).Draw(xgraphics);
								new XLine2D(base.Revit2Client(this.StartXYZ + xyz5 + xyz3), base.Revit2Client(this.StartXYZ + xyz5)).Draw(xgraphics);
								xyz7 = this.StartXYZ + xyz5;
								xyz8 = this.StartXYZ + xyz4 + xyz3;
								thPt = this.StartXYZ + xyz4;
							}
						}
						else if (num2 < Math.PI*.5)
						{
							this.location = FireHydrantLocation.FHL_UPLEFT;
							new XLine2D(base.Revit2Client(this.StartXYZ + xyz4), base.Revit2Client(this.StartXYZ + xyz4 + xyz2)).Draw(xgraphics);
							new XLine2D(base.Revit2Client(this.StartXYZ + xyz4 + xyz2), base.Revit2Client(this.StartXYZ + xyz5 + xyz2)).Draw(xgraphics);
							new XLine2D(base.Revit2Client(this.StartXYZ + xyz5 + xyz2), base.Revit2Client(this.StartXYZ + xyz5)).Draw(xgraphics);
							xyz7 = this.StartXYZ + xyz4;
							xyz8 = this.StartXYZ + xyz5 + xyz2;
							thPt = this.StartXYZ + xyz5;
						}
						else
						{
							this.location = FireHydrantLocation.FHL_DOWNLEFT;
							new XLine2D(base.Revit2Client(this.StartXYZ + xyz4), base.Revit2Client(this.StartXYZ + xyz4 + xyz3)).Draw(xgraphics);
							new XLine2D(base.Revit2Client(this.StartXYZ + xyz4 + xyz3), base.Revit2Client(this.StartXYZ + xyz5 + xyz3)).Draw(xgraphics);
							new XLine2D(base.Revit2Client(this.StartXYZ + xyz5 + xyz3), base.Revit2Client(this.StartXYZ + xyz5)).Draw(xgraphics);
							xyz7 = this.StartXYZ + xyz4;
							xyz8 = this.StartXYZ + xyz5 + xyz3;
							thPt = this.StartXYZ + xyz5;
						}
						new XLine2D(base.Revit2Client(xyz7), base.Revit2Client(xyz8)).Draw(xgraphics);
						this.setShodowLine(xyz7, xyz8, thPt, xgraphics);
						return;
					}
					XYZ xyz9 = new XYZ(0.0, 1.0, 0.0);
					XYZ xyz10 = new XYZ(0.0, -1.0, 0.0);
					XYZ xyz11 = new XYZ(1.0, 0.0, 0.0);
					XYZ xyz12 = new XYZ(-1.0, 0.0, 0.0);
					this.setLineForDraw(xgraphics, xyz9);
					this.setLineForDraw(xgraphics, xyz10);
					this.setLineForDraw(xgraphics, xyz11);
					this.setLineForDraw(xgraphics, xyz12);
					if (xyz.X > this.StartXYZ.X && xyz.Y > this.StartXYZ.Y)
					{
						this.location = FireHydrantLocation.FHL_UPRIGHT;
						new XLine2D(base.Revit2Client(this.StartXYZ + xyz11), base.Revit2Client(this.StartXYZ + xyz11 + xyz9)).Draw(xgraphics);
						new XLine2D(base.Revit2Client(this.StartXYZ + xyz11 + xyz9), base.Revit2Client(this.StartXYZ + xyz12 + xyz9)).Draw(xgraphics);
						new XLine2D(base.Revit2Client(this.StartXYZ + xyz12 + xyz9), base.Revit2Client(this.StartXYZ + xyz12)).Draw(xgraphics);
						new XLine2D(base.Revit2Client(this.StartXYZ + xyz11 + xyz9), base.Revit2Client(this.StartXYZ + xyz12)).Draw(xgraphics);
						return;
					}
					if (xyz.X > this.StartXYZ.X && xyz.Y < this.StartXYZ.Y)
					{
						this.location = FireHydrantLocation.FHL_DOWNRIGHT;
						this.location = FireHydrantLocation.FHL_DOWNRIGHT;
						new XLine2D(base.Revit2Client(this.StartXYZ + xyz11), base.Revit2Client(this.StartXYZ + xyz11 + xyz10)).Draw(xgraphics);
						new XLine2D(base.Revit2Client(this.StartXYZ + xyz11 + xyz10), base.Revit2Client(this.StartXYZ + xyz12 + xyz10)).Draw(xgraphics);
						new XLine2D(base.Revit2Client(this.StartXYZ + xyz12 + xyz10), base.Revit2Client(this.StartXYZ + xyz12)).Draw(xgraphics);
						new XLine2D(base.Revit2Client(this.StartXYZ + xyz11), base.Revit2Client(this.StartXYZ + xyz12 + xyz10)).Draw(xgraphics);
						return;
					}
					if (xyz.X < this.StartXYZ.X && xyz.Y < this.StartXYZ.Y)
					{
						this.location = FireHydrantLocation.FHL_DOWNLEFT;
						this.location = FireHydrantLocation.FHL_DOWNRIGHT;
						new XLine2D(base.Revit2Client(this.StartXYZ + xyz11), base.Revit2Client(this.StartXYZ + xyz11 + xyz10)).Draw(xgraphics);
						new XLine2D(base.Revit2Client(this.StartXYZ + xyz11 + xyz10), base.Revit2Client(this.StartXYZ + xyz12 + xyz10)).Draw(xgraphics);
						new XLine2D(base.Revit2Client(this.StartXYZ + xyz12 + xyz10), base.Revit2Client(this.StartXYZ + xyz12)).Draw(xgraphics);
						new XLine2D(base.Revit2Client(this.StartXYZ + xyz11 + xyz10), base.Revit2Client(this.StartXYZ + xyz12)).Draw(xgraphics);
						return;
					}
					if (xyz.X < this.StartXYZ.X && xyz.Y > this.StartXYZ.Y)
					{
						this.location = FireHydrantLocation.FHL_UPLEFT;
						new XLine2D(base.Revit2Client(this.StartXYZ + xyz11), base.Revit2Client(this.StartXYZ + xyz11 + xyz9)).Draw(xgraphics);
						new XLine2D(base.Revit2Client(this.StartXYZ + xyz11 + xyz9), base.Revit2Client(this.StartXYZ + xyz12 + xyz9)).Draw(xgraphics);
						new XLine2D(base.Revit2Client(this.StartXYZ + xyz12 + xyz9), base.Revit2Client(this.StartXYZ + xyz12)).Draw(xgraphics);
						new XLine2D(base.Revit2Client(this.StartXYZ + xyz11), base.Revit2Client(this.StartXYZ + xyz12 + xyz9)).Draw(xgraphics);
						return;
					}
					this.location = FireHydrantLocation.FHL_DOWNLEFT;
					return;
				}
			}
		}

		private void setShodowLine(XYZ FiPt, XYZ SePt, XYZ ThPt, XGraphics xGraphics)
		{
			XYZ xyz = SePt - ThPt;
			XYZ hdir = FiPt - ThPt;
			XYZ xyz2 = ThPt + 0.25 * xyz;
			XYZ xyz3 = ThPt + 0.5 * xyz;
			XYZ xyz4 = ThPt + 0.75 * xyz;
			XYZ intersect = this.getIntersect(xyz2, hdir, FiPt, SePt);
			XYZ intersect2 = this.getIntersect(xyz3, hdir, FiPt, SePt);
			XYZ intersect3 = this.getIntersect(xyz4, hdir, FiPt, SePt);
			if (intersect != null && intersect2 != null && intersect3 != null)
			{
				new XLine2D(base.Revit2Client(xyz2), base.Revit2Client(intersect)).Draw(xGraphics);
				new XLine2D(base.Revit2Client(xyz3), base.Revit2Client(intersect2)).Draw(xGraphics);
				new XLine2D(base.Revit2Client(xyz4), base.Revit2Client(intersect3)).Draw(xGraphics);
			}
		}

		private XYZ getIntersect(XYZ hFirstPtStart, XYZ hdir, XYZ FiPt, XYZ SePt)
		{
			IntersectionResultArray intersectionResultArray;
			Line.CreateUnbound(hFirstPtStart, hdir).Intersect(Line.CreateBound(FiPt, SePt), out intersectionResultArray);
			if (intersectionResultArray.Size > 0)
			{
				return intersectionResultArray.get_Item(0).XYZPoint;
			}
			return null;
		}

		private void setDirection(XYZ rightVector, ref XYZ leftVector, ref XYZ upVector, ref XYZ downVector)
		{
			leftVector = -rightVector;
			upVector = this.getVVectorX(rightVector)[0];
			downVector = this.getVVectorX(rightVector)[1];
		}

		private List<XYZ> getVVectorX(XYZ rightVector)
		{
			double num = 1.0;
			double num2 = -1.0;
			double num3 = -rightVector.Y * num / rightVector.X;
			double num4 = -rightVector.Y * num2 / rightVector.X;
			return new List<XYZ>
			{
				new XYZ(num3, num, 0.0).Normalize(),
				new XYZ(num4, num2, 0.0).Normalize()
			};
		}

		private List<XYZ> getVVectorY(XYZ rightVector)
		{
			double num = 1.0;
			double num2 = -1.0;
			double num3 = -rightVector.X * num / rightVector.Y;
			double num4 = -rightVector.X * num2 / rightVector.Y;
			return new List<XYZ>
			{
				new XYZ(num, num3, 0.0).Normalize(),
				new XYZ(num2, num4, 0.0).Normalize()
			};
		}

		private void setLineForDraw(XGraphics XGraphics, XYZ direction)
		{
			base.Revit2Client(this.StartXYZ);
			for (int i = 0; i < 6; i++)
			{
				if (i % 2 != 1)
				{
					System.Drawing.Point ptStart = base.Revit2Client(this.StartXYZ + direction * (double)i);
					System.Drawing.Point ptEnd = base.Revit2Client(this.StartXYZ + direction * (double)(i + 1));
					new XLine2D(ptStart, ptEnd).Draw(XGraphics);
				}
			}
		}

		public XYZ StartXYZ;

		private Curve curve;

		public FireHydrantLocation location = FireHydrantLocation.FHL_DOWNLEFT;
	}
}
